package com.kevin.tools.data.mapper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
	List<Mapper> mapperList;
	String lineSeparator = System.getProperty("line.separator");
	{
		mapperList = new ArrayList<Mapper>();
		mapperList.add(new NameMapper(1));
		mapperList.add(new DescMapper(2));
		Collections.sort(mapperList);
	}

	public void buildLeftStr(String leftFileName, String rightFileName) {
		buildLeftStr(leftFileName, rightFileName, null);
	}

	public void buildLeftStr(String leftFileName, String rightFileName,
			String outputFileName) {
		List<Data> leftList = getList(leftFileName);
		List<Data> rightList = getList(rightFileName);
		String result = buildLeftStr(leftList, rightList);
		if (outputFileName == null || "".equals(outputFileName.trim())) {
			System.out.println(result);
			return;
		}
		FileWriter fw=null;
		try {
			fw = new FileWriter(outputFileName);
			fw.write(result);
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fw!=null){
				  fw.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public String buildLeftStr(List<Data> leftList, List<Data> rightList) {
		List<Data> list = buildLeft(leftList, rightList);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < list.size(); i++) {
			Data left = list.get(i);
			String index = format(String.valueOf(i + 1), 3);
			String name = format(left.getName(), 30);
			String desc = format(left.getDesc(), 60);
			sb.append(index).append(name).append(desc);
			Data right = left.getRight();
			if (right != null) {
				index = format(String.valueOf(i + 1), 3);
				name = format(right.getName(), 30);
				desc = format(right.getDesc(), 60);
				sb.append(index).append(name).append(desc)
						.append(lineSeparator);
			} else {
				sb.append(lineSeparator);
			}
		}
		return sb.toString();
	}

	public List<Data> buildLeft(List<Data> leftList, List<Data> rightList) {
		prepare(leftList, rightList);
		findRight(leftList, rightList);
		return leftList;
	}

	private String format(String src, int len) {
		if (src != null && !src.isEmpty() && src.length() < len) {
			src = src.trim();
			int srcLen = src.length();
			int symbolLen = countSymbol(src);
			int zhCNLen = (srcLen - symbolLen) * 2;
			int srcLen2 = zhCNLen + symbolLen;
			StringBuilder s = new StringBuilder(len);
			String placeHolder = " ";
			if (len > srcLen) {
				len = len - srcLen2;
			} else {
				len = 0;
			}
			s.append(src);
			for (int i = 0; i < len; i++) {
				s.append(placeHolder);
			}
			src = s.toString();
		}
		return src;
	}

	private int countSymbol(String s) {
		int count = 0;
		String symbol = "_():;-|.&0123456789abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ";
		char[] charArray = s.toCharArray();
		for (char c : charArray) {
			if (symbol.contains(String.valueOf(c))) {
				count++;
			}
		}
		return count;
	}

	private List<Data> getList(String fileName) {
		BufferedReader br = null;
		List<Data> list = new ArrayList<Data>();
		try {
			File file = new File(fileName);
			FileInputStream fis = new FileInputStream(file);
			InputStreamReader isr = new InputStreamReader(fis, "GBK");
			br = new BufferedReader(isr);
			String s = null;
			while ((s = br.readLine()) != null) {
				s = s.replaceAll(" +", " ");
				String[] split = s.split(" ");
				String name = split[0].trim();
				String desc = split[1].trim();
				Data data = new Data();
				data.setName(name);
				data.setDesc(desc);
				list.add(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
					throw new RuntimeException(e);
				}
			}
		}
		return list;
	}

	private void prepare(List<Data> leftList, List<Data> rightList) {
		int leftSize = leftList.size();
		int rightSize = rightList.size();
		initData(leftList);
		initData(rightList);
		if (leftSize < rightSize) {
			for (int i = leftSize - 1; i < rightSize - 1; i++) {
				Data data = new Data();
				data.setSeq(i + 1);
				leftList.add(data);
			}
		} else if (leftSize > rightSize) {
			for (int i = rightSize - 1; i < leftSize - 1; i++) {
				Data data = new Data();
				data.setSeq(i + 1);
				rightList.add(data);
			}
		}
		return;
	}

	private void initData(List<Data> dataList) {
		for (int i = 0; i < dataList.size(); i++) {
			dataList.get(i).setId(i + 1);
			dataList.get(i).setSeq(i + 1);
		}
	}

	private void findRight(List<Data> leftList, List<Data> rightList) {
		for (int i = 0; i < leftList.size(); i++) {
			Data left = leftList.get(i);
			for2: for (int j = 0; j < rightList.size(); j++) {
				Data right = rightList.get(j);
				for (Mapper mapper : mapperList) {
					if (mapper.map(left, right)) {
						left.setRight(right);
						break for2;
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		String leftFileName = "";
		String rightFileName = "";
		String outputFileName = "";
		String msg = "Args: <leftFileName> <rightFileName> [<outFileName>]";
		if (args.length < 2) {
			System.out.println(msg);
		} else {
			leftFileName = args[0];
			rightFileName = args[1];
			if (args.length == 2) {
				new Main().buildLeftStr(leftFileName, rightFileName);
			} else if (args.length == 3) {
				outputFileName = args[2];
				new Main().buildLeftStr(leftFileName, rightFileName,
						outputFileName);
				System.out.println("It's successful.(see: "+outputFileName+")");
			} else {
				System.out.println(msg);
			}
		}
	}
}
